package service

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"src/mapper"
	"src/model"
)

type Req struct {
	RouterPath   string
	RouterParams map[string]any
	writeHeader  bool
	W            http.ResponseWriter
	R            *http.Request
	Close        bool
	Ret          *model.ReturnModel
	User         *mapper.User
	Params       *map[string]any
}

// 实现Write方法
func (this *Req) Write(b []byte) (int, error) {
	if !this.writeHeader {
		this.WriteHeader(http.StatusOK)
	}
	n, err := this.W.Write(b)
	// 在这里执行你想要的操作
	//this.performAdditionalLogic()
	return n, err
}
func (this *Req) Flush() {
	this.Close = true
	this.W.(http.Flusher).Flush()
}

// 实现WriteHeader方法
func (this *Req) WriteHeader(code int) {
	if this.writeHeader {
		return
	}
	this.W.WriteHeader(code)
	this.writeHeader = true
}

// // 你想要执行的额外逻辑
//
//	func (this *Req) performAdditionalLogic() {
//		// 在这里添加你的逻辑
//	}
func (this *Req) GetParams() map[string]any {
	r := this.R
	// 读取请求体
	var bodyBytes []byte
	if r.Body != nil {
		bodyBytes, _ = ioutil.ReadAll(r.Body)
		r.Body.Close()
	}

	// 将请求体字节重新设置到请求体中，以便其他处理器可以从中读取数据
	if len(bodyBytes) > 0 {
		r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
	}

	// 解析JSON数据
	var params map[string]any
	err := json.Unmarshal(bodyBytes, &params)
	if err == nil {
		this.Params = &params
		return params
	}
	return nil
}
func (b *Req) Next(d func(f *Req)) {
	if b.Close {
		return
	}
	d(b)
	return
}
func New(w http.ResponseWriter, r *http.Request) *Req {
	b := new(Req)
	b.W = w
	b.R = r
	b.Ret = &model.ReturnModel{
		Msg:  "ok",
		Data: nil,
		Code: 200,
	}
	return b
}
func (b *Req) Run(run func(base *Req)) {
	run(b)
	return
}

func (b *Req) Login(run func(base *Req)) {
	token := b.R.Header.Get("token")
	if token == "" {
		b.Fail("缺少参数 token")
		return
	}
	userinfo, err := (&Auth{}).JwtAuth(token)
	if err != nil {
		b.Fail(err.Error())
		return
	}
	b.User = userinfo
	run(b)
	return
}
func (*Req) Auth(b *Req) {
	token := b.R.Header.Get("token")
	if token == "" {
		b.Fail("缺少参数 token")
		return
	}
	userinfo, err := (&Auth{}).JwtAuth(token)
	if err != nil {
		b.Fail(err.Error())
		return
	}
	b.User = userinfo
	return
}
func (b *Req) SetMsg(msg string) *Req {
	b.Ret.Msg = msg
	return b
}
func (b *Req) SetCode(code int) *Req {
	b.Ret.Code = code
	return b
}
func (b *Req) SetDate(data interface{}) *Req {
	b.Ret.Data = data
	return b
}

func (b *Req) Ok(data interface{}) {
	b.Ret.Data = data
	b.SetMsg("ok")
	b.Return(nil)

}
func (b *Req) Fail(str string) {
	b.SetCode(400)
	b.SetMsg(str)
	b.Return(nil)
}
func (b *Req) Return(data *model.ReturnModel) {

	//defer runtime.Go()

	if data != nil {
		b.Ret = data
	}
	jsonStr, _ := json.Marshal(b.Ret)
	_, err := b.Write(jsonStr)
	if err != nil {
		log.Fatalln(err)
		return
	}
	//b.W.(http.Flusher).Flush()
	b.Flush()
	//runtime.Goexit()
	return
}
